home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *RCSid = "$Header: ntp.c,v 2.6 89/02/19 16:08:28 bww Exp $";
- #endif
-
- /*
- * ntp - single shot ntp query
- *
- ****************************************************************
- * HISTORY
- * $Log: ntp.c,v $
- * Revision 2.6 89/02/19 16:08:28 bww
- * SSP headers.
- * [89/02/19 16:05:57 bww]
- *
- * Revision 2.5 88/11/11 16:06:44 bww
- * Upgraded to latest UMD release.
- *
- * Revision 2.4 88/08/20 16:57:27 bww
- * Added FD_ZERO() call and checks for errors from gettimeofday().
- *
- * Revision 2.3 88/08/18 21:12:38 bww
- * Fixed handling of signed octets to be machine independent.
- *
- * Revision 2.2 88/07/17 15:06:37 bww
- * First CMUCS release
- *
- * Revision 2.1 88/04/25 17:59:59 root
- * Initial CMU revision
- *
- * Revision 2.1 88/04/25 17:59:59 root
- * *** empty log message ***
- *
- * Revision 2.0 88/03/31 10:24:58 root
- * *** empty log message ***
- *
- * Revision 1.3 88/02/28 23:24:27 root
- * Fixed precision field
- *
- * Revision 1.2 88/02/28 22:59:10 petry
- * *** empty log message ***
- *
- * Revision 1.1 87/12/16 10:33:10 root
- * Initial revision
- *
- */
-
- /*
- * This program expects a list of host names. It will send off a
- * network time protocol packet and print out the replies on the
- * terminal.
- *
- * Example:
- * % ntp umd1.umd.edu
- * Leap indicator: 0 Status: 1 Stratum: 1 (WWVB)
- * Precision = 2**-10 (dec)
- * Estimated Drift is -6157
- * Synchronizing Dist is 0000.1999
- * Reference Timestamp is 2782090479.031998
- * Originate Timestamp is 2782090483.463761
- * Receive Timestamp is 2782090483.461990
- * Transmit Timestamp is 2782090483.799988
- * Input Timestamp is 2782090483.832143
- * umd1.umd.edu: delay:0.030384 offset:-0.016963
- */
-
- #include <Types.h>
- #include <Events.h>
- #include <Math.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <ErrMgr.h>
- #include <CursorCtl.h>
- #include <Errors.h>
- #include <Devices.h>
- #include <MacTCPCommonTypes.h>
- #include <UDPPB.h>
- #include <TCPPB.h>
- #include <GetMyIPAddr.h>
- #include <AddressXlation.h>
- #include <Time.h>
- #include "ntp.h"
-
- #define TRUE 1
- #define FALSE 0
- #define NIL 0
- #define TICKPERSECOND 60
-
- extern char *malloc();
-
- static StreamPtr myudpstream = 0;
- static short refnum = 0;
- static udp_port myudpport = 0;
-
- extern int errno;
- #ifdef DEBUG
- int debug;
- #endif
-
- void bzero(char * bytes, int len)
- {
- register char *p;
-
- for (p = bytes; len > 0; len--,p++) {
- *p = '\0';
- }
- }
-
- char *inet_ntoa(ip_addr addr)
- {
- static char buf[100];
-
- if (AddrToStr(addr,buf) != noErr) {
- return "?use resolver?";
- } else {
- return buf;
- }
- }
-
- void clean_exit(int code)
- {
- UDPiopb udppb;
-
- if (myudpstream != 0) {
- bzero((char *)&udppb,sizeof(udppb));
- udppb.ioCompletion = NIL;
- udppb.ioCRefNum = refnum;
- udppb.csCode = UDPRelease;
- udppb.udpStream = myudpstream;
- udppb.csParam.create.userDataPtr = NIL;
-
-
- if (PBControl((ParmBlkPtr)&udppb,false) != noErr) {
- fprintf(stderr,"Trouble releasing udp stream in clean_exit(%d)\n",code);
- }
- }
- (void)CloseResolver(); /* ignore errors */
- if (code != 0) {
- fprintf(stderr,"exit(%d)\n",code);
- }
- exit(code);
- }
-
-
- void FailOSErr(msg, err)
- char *msg;
- OSErr err;
- {
- if (err != noErr) {
- fprintf(stderr,"%s errcode=%d\n",msg,err);
- clean_exit (-1);
- }
- }
-
- void ReportOSErr(msg, err)
- char *msg;
- OSErr err;
- {
- if (err != noErr) {
- fprintf(stderr,"%s errcode=%d\n",msg,err);
- }
- }
-
- void
- waitforonesecond()
- {
- register unsigned long ticks;
- for (ticks = TickCount(); TickCount() < (ticks + TICKPERSECOND);) {
- EventRecord theEvent;
-
- (void)EventAvail(0,&theEvent);
- /* packet(); checks for incoming packets */
- }
- }
-
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- struct hostInfo hp;
- ip_addr clock_host, whofrom;
- struct l_fixedpt in_timestamp;
- static struct ntpdata ntp_data;
- struct ntpdata *pkt = &ntp_data;
- struct timeval tp;
- int host, retry;
- double ul_fixed_to_double();
- double ref, t1, t2, t3, t4, offset, delay;
- char ref_clock[5];
- UDPiopb udppb;
- wdsEntry wds[2];
- char * p;
- int len;
- OSErr err;
-
-
- InitCursorCtl(nil);
- FailOSErr("OpenResolver", OpenResolver(NIL));
- FailOSErr("Can't open driver",opendriver(".IPP",&refnum));
-
- ref_clock[4] = NULL;
-
- /* grab a udp port, to use for sending packets. NoDelay, Async */
-
- p = malloc(4096);
- if (p == NULL) {
- fprintf(stderr,"malloc fails\n");
- clean_exit(-1);
- }
- bzero((char *)&udppb,sizeof(udppb));
- udppb.ioCompletion = NIL;
- udppb.ioCRefNum = refnum;
- udppb.csCode = UDPCreate;
- udppb.csParam.create.rcvBuff = p;
- udppb.csParam.create.rcvBuffLen = 4096;
- udppb.csParam.create.notifyProc = NIL;
- udppb.csParam.create.localPort = 0;
- udppb.csParam.create.userDataPtr = 0;
-
- FailOSErr("UDPCreate Fails",PBControl((ParmBlkPtr)&udppb,false));
-
- myudpstream = udppb.udpStream;
- myudpport = udppb.csParam.create.localPort;
-
- retry = RETRY_COUNT;
-
-
- for (host = 1; host < argc; ++host) {
- if (argv[host] == NULL)
- continue;
- if (StrToAddr(argv[host],&hp,NIL,NIL) != noErr) {
- fprintf(stderr, "\nNo such host: %s (use IP address for now)\n",
- argv[host]);
- continue;
- }
-
- bzero((char *)pkt, sizeof(ntp_data));
-
- pkt->status = NTPVERSION_1;
- pkt->stratum = UNSPECIFIED;
- pkt->poll = 0;
- pkt->org.int_part = pkt->org.fraction = 0;
- pkt->rec.int_part = pkt->rec.fraction = 0;
-
- /*
- * Needed to fill in the transmit time stamp field
- */
- if (gettimeofday(&tp, (struct timezone *) 0) == -1) {
- perror("ntp gettimeofday1");
- clean_exit(1);
- }
- tstamp(&pkt->xmt, &tp);
-
- udppb.ioCompletion = NIL;
- udppb.ioCRefNum = refnum;
- udppb.csCode = UDPWrite;
- udppb.udpStream = myudpstream;
- udppb.csParam.send.remoteHost = hp.addr[0];
- udppb.csParam.send.remotePort = NTP_PORT;
- udppb.csParam.send.userDataPtr = NIL;
-
- /* build write-data structure */
- wds[0].length = sizeof(ntp_data);
- wds[0].ptr = (char *) &ntp_data;
- wds[1].length = 0;
-
- udppb.csParam.send.wdsPtr = (Ptr)&wds;
-
- err = PBControl((ParmBlkPtr)&udppb,false);
- if (err == ipDestDeadErr) { /* are there other codes here we should special case? */
- fprintf(stderr,"Host %s not responding, errcode=%d\n",inet_ntoa(hp.addr[0]),err);
- continue;
- } else if (err != noErr) {
- fprintf(stderr,"UDPsend fails errcode=%d\n",err);
- continue;
- }
-
- /*
- * Wait for the reply.
- */
- bzero((char *)&udppb,sizeof(udppb));
- udppb.ioCompletion = NIL;
- udppb.ioCRefNum = refnum;
- udppb.csCode = UDPRead;
- udppb.udpStream = myudpstream;
- udppb.csParam.receive.timeOut = TIME_OUT; /* minimum time */
- udppb.csParam.receive.secondTimeStamp = 0;
- udppb.csParam.receive.userDataPtr = NIL;
- err = PBControl((ParmBlkPtr)&udppb,false);
-
- if (err == commandTimeout) {
- fprintf(stderr,"\n\t* Timeout *\n");
- if (--retry)
- --host;
- else {
- fprintf(stderr,"\nHost %s is not responding\n",
- argv[host]);
- retry = RETRY_COUNT;
- }
- continue;
- } else if (err != noErr) {
- fprintf(stderr,"packet:UDPRead fails (%d)\n", err);
- continue;
- }
- whofrom = udppb.csParam.receive.remoteHost;
-
- /* copy bytes into pkt */
- len = udppb.csParam.receive.rcvBuffLen;
-
- memcpy (&ntp_data, udppb.csParam.receive.rcvBuff,
- (sizeof(ntp_data) > len) ? (len) : (sizeof(ntp_data)));
-
- /* release buffer space */
- udppb.csCode = UDPBfrReturn;
- if (PBControl((ParmBlkPtr)&udppb,false) != noErr) {
- fprintf(stderr,"packet:UDPBfrReturn fails\n");
- }
- if (sizeof(ntp_data) != len) {
- fprintf(stderr,"packet was %d bytes, expected %d\n",len,sizeof(ntp_data));
- }
-
- if (gettimeofday(&tp, (struct timezone *) 0) == -1) {
- perror("ntp gettimeofday2");
- clean_exit(1);
- }
- tstamp(&in_timestamp, &tp);
-
- printf("Packet from: [%s]\n", inet_ntoa(whofrom));
- printf("Leap indicator: %d\tStatus: %d\tStratum: %d",
- (int)(pkt->status >> 6), (int)(pkt->status & 0x03f),
- pkt->stratum);
- switch (pkt->stratum) {
- case 0:
- case 1:
- (void) strncpy(ref_clock, (char *) &pkt->refid, 4);
- ref_clock[4] = '\0';
- printf(" (%s)\n", ref_clock);
- break;
- default:
- clock_host = (u_long) pkt->refid;
- printf(" [%s]\n", inet_ntoa(clock_host));
- break;
- }
- printf("Poll = %d Precision = 2**%d (dec)\n",
- pkt->poll, char_to_int(pkt->precision));
- printf("Estimated Drift is %ld\n",
- (long) ntohl((u_long) pkt->drift));
- printf("Synchronizing Dist is %04X.%04X\n",
- ntohs((u_short) pkt->distance.sint_part),
- ntohs((u_short) pkt->distance.sfraction));
-
- ref = ul_fixed_to_double(&pkt->reftime);
- t1 = ul_fixed_to_double(&pkt->org);
- t2 = ul_fixed_to_double(&pkt->rec);
- t3 = ul_fixed_to_double(&pkt->xmt);
- t4 = ul_fixed_to_double(&in_timestamp);
-
- printf("Reference Timestamp is %08lx.%08lx %f\n",
- ntohl(pkt->reftime.int_part),
- ntohl(pkt->reftime.fraction), ref);
- printf("Originate Timestamp is %08lx.%08lx %f\n",
- ntohl(pkt->org.int_part),
- ntohl(pkt->org.fraction), t1);
- printf("Receive Timestamp is %08lx.%08lx %f\n",
- ntohl(pkt->rec.int_part),
- ntohl(pkt->rec.fraction), t2);
- printf("Transmit Timestamp is %08lx.%08lx %f\n",
- ntohl(pkt->xmt.int_part),
- ntohl(pkt->xmt.fraction), t3);
- printf("Input Timestamp is %08lx.%08lx %f\n",
- ntohl(in_timestamp.int_part),
- ntohl(in_timestamp.fraction), t4);
-
- delay = (t4 - t1) - (t3 - t2);
- offset = (t2 - t1) + (t3 - t4);
- offset = offset / 2.0;
- printf("%s: delay:%f offset:%f\n\n", argv[host], delay, offset);
- (void) fflush(stdout);
- } /* end of for each host */
- clean_exit(0);
- } /* end of main */
-